home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Kit PC World De Ampliacion De Windows 95
/
Kit PC World de ampliacion de Windows 95.iso
/
internet
/
sweeper
/
samples
/
olecon~1
/
framewrk
/
internet.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-05
|
9KB
|
465 lines
#include "IPServer.H"
#include "Internet.H"
#include "Util.H"
static VARTYPE rgI4[] = { VT_I4 };
typedef enum {
InternetEvent_Progress = 0,
InternetEvent_ReadyStateChange = 1
} INTERNETEVENTS;
static EVENTINFO rgEvents [] = {
{ DISPID_PROGRESS, 1, rgI4 }, // (long percentDone)
{ DISPID_READYSTATECHANGE, 1, rgI4 }, // (OLE_READYSTATE newState)
};
// local class for doing async monitoring. It's not really all that
// general purpose, but it does the job...
class CDownloadSink : public IBindStatusCallback
{
public:
CDownloadSink(IUnknown *punkOuter,CInternetControl *,DISPID );
~CDownloadSink();
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
STDMETHOD(GetBindInfo)(
DWORD * grfBINDF,
BINDINFO *pbindinfo);
STDMETHOD(OnStartBinding)(
IBinding *pib);
STDMETHOD(GetPriority)(
LONG *pnPriority);
STDMETHOD(OnProgress)(
ULONG ulProgress,
ULONG ulProgressMax,
ULONG ulStatusCode,
LPCWSTR pwzStatusText);
STDMETHOD(OnDataAvailable )(
DWORD grfBSCF,
DWORD dwSize,
FORMATETC *pfmtetc,
REFIID riid,
IUnknown *punk);
STDMETHOD(OnLowResource)(
DWORD reserved);
STDMETHOD(OnStopBinding)(
HRESULT hrError);
CDownloadSink * Next() { return(m_next); }
void Next(CDownloadSink *n) { m_next = n; }
DISPID DispId() { return(m_propId); }
IBinding * Binding() { return(m_binding); }
private:
CDownloadSink * m_next;
CInternetControl * m_control;
DISPID m_propId;
IBinding * m_binding;
DWORD m_ref;
};
CDownloadSink::CDownloadSink
(
IUnknown * punkOuter,
CInternetControl * control,
DISPID propId
)
{
// CHECK_POINTER(control);
m_control = control;
m_control->AddRef();
m_propId = propId;
m_next = 0;
m_binding = 0;
m_ref = 0;
}
CDownloadSink::~CDownloadSink()
{
if( m_control )
m_control->Release();
if( m_binding )
m_binding->Release();
}
STDMETHODIMP
CDownloadSink::QueryInterface(const GUID &iid,void **ppv )
{
if( IsEqualGUID(iid,IID_IUnknown) || IsEqualGUID(iid,IID_IBindStatusCallback) )
{
*ppv = this;
AddRef();
return(NOERROR);
}
return( E_NOINTERFACE );
}
STDMETHODIMP_(ULONG)
CDownloadSink::AddRef()
{
return(++m_ref);
}
STDMETHODIMP_(ULONG)
CDownloadSink::Release()
{
if(!--m_ref)
{
delete this;
return(0);
}
return( m_ref );
}
STDMETHODIMP
CDownloadSink::GetBindInfo( DWORD *grfBINDF, BINDINFO *pbindInfo)
{
*grfBINDF = BINDF_ASYNCHRONOUS;
pbindInfo->szExtraInfo = 0;
return(NOERROR);
}
STDMETHODIMP
CDownloadSink::OnStartBinding(IBinding *pib)
{
m_binding = pib;
pib->AddRef();
return(NOERROR);
}
STDMETHODIMP
CDownloadSink::GetPriority( LONG *pnPriority)
{
return(E_NOTIMPL);
}
STDMETHODIMP
CDownloadSink::OnProgress
(
ULONG ulProgress,
ULONG ulProgressMax,
ULONG ulStatusCode,
LPCWSTR pwzStatusText
)
{
return(m_control->OnProgress(m_propId,ulProgress,
ulProgressMax,ulStatusCode,pwzStatusText) );
}
STDMETHODIMP
CDownloadSink::OnDataAvailable
(
DWORD grfBSCF,
DWORD dwSize,
FORMATETC * pFmtetc,
REFIID iid,
IUnknown * punk
)
{
return(m_control->OnData(m_propId,grfBSCF,(IStream *)punk, dwSize ));
}
STDMETHODIMP
CDownloadSink::OnLowResource( DWORD reserved)
{
m_binding->Abort();
return(S_OK);
}
STDMETHODIMP
CDownloadSink::OnStopBinding(HRESULT hrError)
{
m_binding->Release();
m_binding = 0;
m_control->Release();
m_control = 0;
return(NOERROR);
}
//------------------------------------------------------
//
// class CInternetControl
//
//
CInternetControl::CInternetControl
(
IUnknown * pUnkOuter,
int iPrimaryDispatch,
void * pMainInterface
)
: COleControl(pUnkOuter,iPrimaryDispatch,pMainInterface)
{
m_downloads = 0;
m_host = 0;
m_readyState = READYSTATE_LOADING;
}
CInternetControl::~CInternetControl()
{
if( m_downloads )
{
CDownloadSink * next;
do
{
next = m_downloads->Next();
IBinding * binding = m_downloads->Binding();
if( binding )
binding->Abort();
m_downloads->Release();
} while ( (m_downloads = next) != 0 );
}
if( m_host )
m_host->Release();
}
HRESULT CInternetControl::InternalQueryInterface
(
REFIID riid,
void **ppvObjOut
)
{
IUnknown *pUnk;
*ppvObjOut = NULL;
if (DO_GUIDS_MATCH(riid, IID_IServiceProvider)) {
pUnk = (IUnknown *)(IServiceProvider *)this;
} else{
return COleControl::InternalQueryInterface(riid, ppvObjOut);
}
pUnk->AddRef();
*ppvObjOut = (void *)pUnk;
return S_OK;
}
STDMETHODIMP
CInternetControl::QueryService(REFGUID guidService,
REFIID riid, void **ppvObject)
{
HRESULT hr;
IServiceProvider * clientsProvider;
hr = m_pClientSite->QueryInterface(IID_IServiceProvider,
(void**)&clientsProvider );
if( SUCCEEDED(hr) )
{
hr = clientsProvider->QueryService(guidService,
riid,ppvObject);
clientsProvider->Release();
}
return(hr);
}
HRESULT
CInternetControl::GetBindHost(IBindHost ** pHost )
{
HRESULT hr;
if( !m_host )
hr = GetBindHost();
else
hr = NOERROR;
*pHost = m_host;
return(hr);
}
HRESULT
CInternetControl::GetBindHost()
{
if( m_host )
return(NOERROR);
IServiceProvider * serviceProvider = 0;
HRESULT hr = m_pClientSite->QueryInterface
(
IID_IServiceProvider,
(void**)&serviceProvider
);
if( SUCCEEDED(hr) )
hr = serviceProvider->QueryService( SID_BindHost, IID_IBindHost,
(void**)&m_host );
else
hr = E_FAIL; // C_E_UNKNOWNSERVICE;
return(hr);
}
HRESULT CInternetControl::GetAMoniker( LPOLESTR url, IMoniker ** ppmkr )
{
HRESULT hr = GetBindHost();
if( SUCCEEDED(hr) )
hr = m_host->ParseDisplayName(url,ppmkr);
if( FAILED(hr) )
// FUTURE: This really should be a call to MkParseDisplayNameEx!!!
hr = ::CreateURLMoniker(0,url,ppmkr);
return( hr );
}
HRESULT CInternetControl::SetupDownload( IMoniker * moniker, DISPID propId )
{
HRESULT hr = GetBindHost();
IBindCtx * pBindCtx = 0;
if( SUCCEEDED(hr) )
hr = m_host->GetBindCtx(0,&pBindCtx);
if( FAILED(hr) )
hr = ::CreateBindCtx(0,&pBindCtx);
CDownloadSink * sink = 0;
if( SUCCEEDED(hr) )
{
sink = new CDownloadSink(0,this,propId);
if( sink )
sink->AddRef();
}
if( SUCCEEDED(hr) && !sink )
hr = E_OUTOFMEMORY;
if( SUCCEEDED(hr) )
{
// FUTURE: This should be a call to RegisterBindStatusCallback!!
hr = pBindCtx->RegisterObjectParam(OLESTR("BindStatusCallback"), sink );
}
IStream * strm = 0;
if( SUCCEEDED(hr) )
hr = moniker->BindToStorage( pBindCtx, 0, IID_IStream, (void**)&strm );
if( strm )
strm->Release();
if( pBindCtx )
pBindCtx->Release();
if( FAILED(hr) && sink )
sink->Release();
if( SUCCEEDED(hr) )
{
if( m_downloads )
m_downloads->Next(sink);
m_downloads = sink;
}
return(hr);
}
HRESULT CInternetControl::SetupDownload( LPOLESTR url, DISPID propId )
{
CHECK_POINTER(url);
IMoniker * pmkr;
HRESULT hr = GetAMoniker( url, &pmkr );
if( SUCCEEDED(hr) )
return( SetupDownload(pmkr,propId) );
return(hr);
}
HRESULT CInternetControl::SetupDownload( IStream * propStream, DISPID propId )
{
CHECK_POINTER(propStream);
IMoniker * pmkr;
HRESULT hr = ::OleLoadFromStream(propStream,IID_IMoniker,(void**)&pmkr);
if( SUCCEEDED(hr) )
return( SetupDownload(pmkr,propId) );
return(hr);
}
HRESULT CInternetControl::OnData( DISPID, DWORD,IStream *, DWORD)
{
return(NOERROR);
}
HRESULT CInternetControl::OnProgress( DISPID, ULONG progress, ULONG themax, ULONG, LPCWSTR)
{
return(NOERROR);
}
HRESULT CInternetControl::GetBinding(DISPID dispId,IBinding** ppBinding)
{
CHECK_POINTER(ppBinding);
CDownloadSink * sink = m_downloads;
while(sink)
{
if( sink->DispId() == dispId )
{
if( (*ppBinding = sink->Binding()) == 0 )
return( E_PENDING );
return(S_OK);
}
sink = sink->Next();
}
return(E_FAIL);
}
HRESULT CInternetControl::FireReadyStateChange( long newState )
{
FireEvent( &::rgEvents[InternetEvent_ReadyStateChange], m_readyState = newState );
return(S_OK);
}
HRESULT CInternetControl::FireProgress( ULONG dwAmount )
{
FireEvent( &::rgEvents[InternetEvent_Progress], dwAmount );
return(S_OK);
}